#include "CServer.h"
#include<iostream>
#include<memory>
#include "HttpConnection.h"
#include "IOContextPool.h"
CServer::CServer(boost::asio::io_context& ioc, unsigned short& port):_acceptor(ioc,tcp::endpoint(tcp::v4(),port)),_ioc(ioc),_socket(ioc)
{

	
}


//通过回调函数形成监听链，开始进行消息接受和发送,但是此时是http服务，不会再同一个TCP连接上发生多次读事件
//对于服务器是由可能出现多和客户端的连接的，所以通过回调函数实现监听连
//回调事件结束，是一回调函数执行完成周，这个事件就从事件树上结束了，释放
void CServer::Start()
{
	auto self = shared_from_this();															//异步使用，避免Cserver被释放，但是挂在事件树上的还指向一段空间，最终野指针
	_acceptor.async_accept(_socket, [self](beast::error_code ec) {
		try {
			
			if (ec) {
				self->Start();																//出错则放弃这个连接，继续监听新链接
				return;
			}
			std::make_shared<HttpConnection>(std::move(self->_socket))->Start();			//处理新链接，创建HpptConnection类管理新连接，同时调用连接类的start，开始服务
																							//最好多一个东西存放那个HttpConnection，由于这里是异步的，可能会出现这样一种状况
																							//挂到事件树上了，但是这里结束之后，资源就释放了，所以使用self指针，保证在事件树执行完成之前都不会被释放

			//每一个IOService 是运行在不同的线程上的
			self->_socket = boost::asio::ip::tcp::socket(AsioIOServicePool::GetInstance()->GetIOService());//重新安排一个socket，供下一个客户端使用，原先的被move了，不可以使用
			//重新申请一个socket
			self->Start();																	//继续监听，最保险的状态，是重新创建一个socket，原先的socket会被用于管理客户端
		}
		catch (std::exception& exp) {
			std::cout << "exception is " << exp.what() << std::endl;
			self->Start();
		}
		});
}
